package com.noname.lib_base_java.mvp;

import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.noname.lib_base_java.db.download.DowanloadDBManager;
import com.noname.lib_base_java.entity.FielBean;
import com.noname.lib_base_java.entity.NetFielBean;
import com.noname.lib_base_java.net.download.DownloadInfo;
import com.noname.lib_base_java.net.download.DownloadManager;
import com.noname.lib_base_java.util.L;

import org.json.JSONObject;
import org.json.JSONTokener;

import java.lang.reflect.Type;
import java.util.List;

import io.reactivex.Observer;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import okhttp3.ResponseBody;

/**
 * Author: Lmoumou
 * Date: 2018-12-10 14:12
 * 文件名: BasePresenterImpl
 * 描述:
 */
public abstract class BasePresenterImpl<V extends BaseContract.BaseView, M extends BaseContract.BaseModel>
        implements BaseContract.BasePresenter {
    protected V mView;
    protected M mModel = creatModel();


    protected abstract M creatModel();

    public BasePresenterImpl(V view) {
        this.mView = view;
    }

    private CompositeDisposable compositeDisposable = new CompositeDisposable();

    private CompositeDisposable compositeDisposabled = new CompositeDisposable();

    @Override
    public void detachView() {
        if (!compositeDisposable.isDisposed()) {
            compositeDisposable.dispose();
        }
        compositeDisposable.dispose();
    }

    @Override
    public void pUpLoadFiel(List<FielBean> fielList) {
        mView.showLoadDialog();

        mModel.mUpLoadFiel(new FielObserver() {
            @Override
            protected void onSuccess(List<NetFielBean> fielBeens) {
                mView.upLoadFiels(fielBeens);
            }


            @Override
            public void onError(int status, String msg) {
                mView.upLoadFielsFail(msg);
            }
        }, fielList);
    }

    @Override
    public void pUpLoadFiel(FielBean fielBean) {
        mView.showLoadDialog();
        mModel.mUpLoadFiel(new FielObserver() {
            @Override
            protected void onSuccess(List<NetFielBean> fielBeens) {
            }

            @Override
            public void onError(int status, String msg) {
                mView.upLoadFielsFail(msg);
            }
        }, fielBean);
    }

    public abstract class FielObserver implements Observer<ResponseBody> {
        private Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();

        @Override
        public void onComplete() {

        }

        @Override
        public void onSubscribe(Disposable d) {
            compositeDisposable.add(d);
        }

        @Override
        public void onNext(ResponseBody body) {
            try {
                if (body == null) {
                    onError(0, "服务器异常");
                    return;
                }
                String res = body.string();
                JSONTokener jsonParser = new JSONTokener(res);
                JSONObject root = (JSONObject) jsonParser.nextValue();
                int status = 0;
                String msg = "";
                String data = "";
                if (root.has("error_code")) {
                    status = root.getInt("error_code");
                }
                if (root.has("msg")) {
                    msg = root.getString("msg");
                }
                if (root.has("body")) {
                    data = root.getString("body");
                }
                if (status == 0) {
                    List<NetFielBean> fielBeens = gson.fromJson(data, new TypeToken<List<NetFielBean>>() {
                    }.getType());
                    onSuccess(fielBeens);
                } else {
                    onError(status, msg);
                }
            } catch (Exception e) {
                e.printStackTrace();
                L.e("FielObserver", "异常->" + e.getMessage());
            }

        }

        @Override
        public void onError(Throwable e) {
            mView.onNetError(e.getMessage());
        }

        protected abstract void onSuccess(List<NetFielBean> fielBeens);

        abstract public void onError(int status, String msg);
    }

    @Override
    public void pDownload(DownloadInfo info, DownloadManager.ProgressListener progressObserver) {
        mModel.mDownload(new Observer<DownloadInfo>() {
            @Override
            public void onSubscribe(Disposable d) {
                compositeDisposabled.add(d);
            }

            @Override
            public void onNext(DownloadInfo downloadInfo) {
                DowanloadDBManager.getInstance().saveContact(downloadInfo);
                mView.vDownload(downloadInfo);
            }

            @Override
            public void onError(Throwable e) {
                mView.vDownloadFail(e.getMessage());
                mView.hideLoadDialog();
            }

            @Override
            public void onComplete() {

            }
        }, info, progressObserver);
    }

    /**
     * 常用Observer
     *
     * @param <T>
     */
    public abstract class CommonObserver<T> implements Observer<ResponseBody> {
        private Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        private Type type;

        public CommonObserver(Type type) {
            this.type = type;
        }

        @Override
        public void onComplete() {

        }

        @Override
        public void onSubscribe(Disposable d) {
            compositeDisposable.add(d);
        }

        @Override
        public void onNext(ResponseBody body) {
            try {
                if (body == null) {
                    onError(0, "服务器异常");
                    return;
                }
                String res = body.string();
                JSONTokener jsonParser = new JSONTokener(res);
                JSONObject root = (JSONObject) jsonParser.nextValue();
                int status = 0;
                String msg = "";
                String data = "";
                if (root.has("code")) {
                    status = root.getInt("code");
                }
                if (root.has("msg")) {
                    msg = root.getString("msg");
                }
                if (root.has("body")) {
                    data = root.getString("body");
                }
                T t;
                if (type.equals(String.class)) {
                    t = (T) data;
                } else {
                    if (data != null && !data.equals("")) {
                        t = gson.fromJson(res, type);
                    } else {
                        t = null;
                    }
                }
                switch (status) {
                    case 200:
                        onSuccess(t);
                        break;
                    case 1005:
                        mView.onNoLogin();
                        break;
                    default:
                        // view.doPrompt(msg);
                        onError(status, msg);
                        break;
                }

            } catch (Exception e) {
                e.printStackTrace();
                Log.e("CommonObserver", "数据异常->" + e.getMessage());
            }
        }

        @Override
        public void onError(Throwable e) {
            mView.onNetError(e.getMessage());
            Log.e("CommonObserver", "异常信息->" + e.getMessage());
        }

        protected abstract void onSuccess(T t);

        abstract public void onError(int status, String msg);
    }

    @Override
    public void pPause() {
        compositeDisposabled.dispose();
        mModel.mPause();

    }
}
